package imgshare.shiro;

import cn.hutool.json.JSONUtil;
import imgshare.common.api.CommonResult;
import imgshare.util.JWTUtil;
import io.jsonwebtoken.Claims;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JWTFilter extends AuthenticatingFilter {

    @Autowired
    private JWTUtil jwtUtil;

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String jwt = httpServletRequest.getHeader("Authorization");
        if(StringUtils.isEmpty(jwt)){
            return true;
        }else{
            // 校验jwt
            Claims claims = jwtUtil.getClaimsByToken(jwt);
            if (claims==null || jwtUtil.isTokenExpired(claims.getExpiration())){ //token是否为空或过期
                throw new ExpiredCredentialsException("Token is invalid please login again");
            }
            // 执行登录
            return executeLogin(servletRequest,servletResponse);
        }
    }

    /**
     * 捕获登录异常
     * @param token
     * @param e
     * @param request
     * @param response
     * @return
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
                                     ServletRequest request, ServletResponse response) {

        HttpServletResponse servletResponse  = (HttpServletResponse) response;

        Throwable throwable = e.getCause() == null ? e : e.getCause();
        CommonResult errorResult = CommonResult.failed(throwable.getMessage());

        // 将错误信息封装为json数据后返回给前端
        String errorResultJson = JSONUtil.toJsonStr(errorResult);
        try {
            servletResponse.getWriter().println(errorResultJson);
        } catch (IOException ex) {
            //ex.printStackTrace();
        }
        return false;
    }


    @Override
    protected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String jwt = httpServletRequest.getHeader("Authorization");
        return jwt.isEmpty()?null:new JWTToken(jwt);
    }

    /**
     * 对跨域提供支持
     */
//    @Override
//    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
//        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
//        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
//        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
//        // 跨域时会首先发送一个option请求，这里我们给option请求直接返回正常状态
//        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
//            httpServletResponse.setStatus(HttpStatus.OK.value());
//            return false;
//        }
//        return super.preHandle(request, response);
//    }
}
